Skip to content

fix: separate HTTP bind host from gRPC gateway target host#2824

Merged
omer-topal merged 1 commit intomasterfrom
fix/separate-http-grpc-target-host
Mar 10, 2026
Merged

fix: separate HTTP bind host from gRPC gateway target host#2824
omer-topal merged 1 commit intomasterfrom
fix/separate-http-grpc-target-host

Conversation

@omer-topal
Copy link
Copy Markdown
Contributor

@omer-topal omer-topal commented Mar 10, 2026

Summary by CodeRabbit

  • New Features

    • Added server.host configuration option to specify which interface/host the HTTP server binds to
    • Added http-grpc-target-host configuration option and environment variable to specify where the HTTP gateway connects to the local gRPC server
  • Documentation

    • Updated configuration documentation to reflect new server host and HTTP gateway connectivity options with corresponding environment variable mappings

@omer-topal omer-topal requested a review from ucatbas March 10, 2026 12:13
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

This PR adds two new server configuration options: server.host for binding the HTTP server to a specific interface (default: empty string) and http.grpc_target_host for specifying the host the HTTP gateway uses to connect to the local gRPC server (default: 127.0.0.1). The changes include configuration struct additions, command-line flags, environment variable bindings, documentation updates, and a modification to how the gRPC client target address is constructed.

Changes

Cohort / File(s) Summary
Configuration Structure
internal/config/config.go, internal/config/config_test.go
Added GRPCTargetHost field to HTTP config struct with default "127.0.0.1"; changed HTTP.Host default from "127.0.0.1" to empty string; added test assertions for new defaults.
Documentation & Examples
docs/setting-up/configuration.mdx, example.config.yaml
Updated configuration documentation and example YAML to include server.host and http.grpc_target_host fields with their ENV variable mappings (PERMIFY_SERVER_HOST, PERMIFY_HTTP_GRPC_TARGET_HOST).
Command-Line Flags & Bindings
pkg/cmd/flags/serve.go, pkg/cmd/serve.go, pkg/cmd/config.go
Added Viper flag bindings for server-host and http-grpc-target-host; added corresponding CLI flag definitions and configuration rendering entries.
Server Implementation
internal/servers/server.go
Changed gRPC client target construction to use HTTP.GRPCTargetHost instead of deriving it from server host, enabling independent configuration of the gRPC gateway connection target.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • tolgaozen

Poem

🐰 Two new hosts hop into place,

Server and gateway find their space,

Configuration blooms with care,

Bindings woven everywhere! 🌱

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: separating HTTP bind host from gRPC gateway target host configuration, which aligns with all file changes adding server.host and http.grpc_target_host fields.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/separate-http-grpc-target-host

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/servers/server.go (1)

262-273: ⚠️ Potential issue | 🟠 Major

The new default gRPC dial host can break TLS handshakes.

Line 272 dials server.http.grpc_target_host (default 127.0.0.1), while Line 263 passes srv.NameOverride (which defaults to empty) to credentials.NewClientTLSFromFile(). When the server name override is empty, gRPC uses the dial target hostname for TLS certificate verification. This means certificates issued for a DNS name will fail hostname verification against 127.0.0.1, even though the gateway is connecting to the same local gRPC server. Ensure certificates match the dial target hostname or set server.name_override to the certificate's CN/SAN when deploying with TLS.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/servers/server.go` around lines 262 - 273, When TLS is enabled,
compute a single serverName variable and use it both when creating TLS
credentials and when building the dial target so hostname verification uses the
intended name: set serverName := srv.NameOverride; if serverName == "" then
fallback to srv.HTTP.GRPCTargetHost; call
credentials.NewClientTLSFromFile(srv.GRPC.TLSConfig.CertPath, serverName) and
build targetAddr with net.JoinHostPort(serverName, srv.GRPC.Port) (instead of
using srv.NameOverride in one place and srv.HTTP.GRPCTargetHost in the other) so
the dial hostname matches the certificate CN/SAN.
🧹 Nitpick comments (1)
pkg/cmd/flags/serve.go (1)

32-37: Add a regression test for these new bindings.

These lines are the only thing that makes the new knobs reachable from flags/env, and the config tests in this PR only cover YAML/default loading. A small table-driven test for server-host / http-grpc-target-host and the matching PERMIFY_* vars would make this wiring much harder to break later.

Also applies to: 90-95

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cmd/flags/serve.go` around lines 32 - 37, Add a table-driven regression
test (e.g., TestFlagEnvBindings) in the pkg/cmd/flags package that verifies
viper.BindPFlag and viper.BindEnv wiring for the new knobs: "server-host" and
"http-grpc-target-host" (and their env names PERMIFY_SERVER_HOST and
PERMIFY_HTTP_GRPC_TARGET_HOST). For each case, set up the flags (simulate
passing --server-host/--http-grpc-target-host), set the corresponding
environment variable, call the same initialization that runs
viper.BindPFlag/viper.BindEnv (the code in serve.go that calls viper.BindPFlag
and viper.BindEnv), then assert viper.GetString("server.host") /
viper.GetString("http.grpc_target_host") returns the expected value; reset viper
and flags between cases to avoid cross-test pollution. Ensure the test covers
both flag-precedence and env-only scenarios.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/config/config.go`:
- Around line 288-292: The server default currently sets Host = "" which binds
to all interfaces; change the default to loopback-only by setting Host to
"127.0.0.1" (or "::1" if IPv6 desired) while leaving HTTP.GRPCTargetHost
(server.http.grpc_target_host) unchanged for internal gRPC dialing; update the
default in the config struct where Host and HTTP (Enabled, Port, GRPCTargetHost)
are initialized so the HTTP server binds to loopback by default but continues to
use GRPCTargetHost for the internal dial path.

---

Outside diff comments:
In `@internal/servers/server.go`:
- Around line 262-273: When TLS is enabled, compute a single serverName variable
and use it both when creating TLS credentials and when building the dial target
so hostname verification uses the intended name: set serverName :=
srv.NameOverride; if serverName == "" then fallback to srv.HTTP.GRPCTargetHost;
call credentials.NewClientTLSFromFile(srv.GRPC.TLSConfig.CertPath, serverName)
and build targetAddr with net.JoinHostPort(serverName, srv.GRPC.Port) (instead
of using srv.NameOverride in one place and srv.HTTP.GRPCTargetHost in the other)
so the dial hostname matches the certificate CN/SAN.

---

Nitpick comments:
In `@pkg/cmd/flags/serve.go`:
- Around line 32-37: Add a table-driven regression test (e.g.,
TestFlagEnvBindings) in the pkg/cmd/flags package that verifies viper.BindPFlag
and viper.BindEnv wiring for the new knobs: "server-host" and
"http-grpc-target-host" (and their env names PERMIFY_SERVER_HOST and
PERMIFY_HTTP_GRPC_TARGET_HOST). For each case, set up the flags (simulate
passing --server-host/--http-grpc-target-host), set the corresponding
environment variable, call the same initialization that runs
viper.BindPFlag/viper.BindEnv (the code in serve.go that calls viper.BindPFlag
and viper.BindEnv), then assert viper.GetString("server.host") /
viper.GetString("http.grpc_target_host") returns the expected value; reset viper
and flags between cases to avoid cross-test pollution. Ensure the test covers
both flag-precedence and env-only scenarios.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a6b2739c-e58c-4fc9-9adc-538de14bfbe0

📥 Commits

Reviewing files that changed from the base of the PR and between 34412bf and fcac8d1.

📒 Files selected for processing (8)
  • docs/setting-up/configuration.mdx
  • example.config.yaml
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/servers/server.go
  • pkg/cmd/config.go
  • pkg/cmd/flags/serve.go
  • pkg/cmd/serve.go

Comment thread internal/config/config.go
Comment on lines +288 to +292
Host: "",
HTTP: HTTP{
Enabled: true,
Port: "3476",
Enabled: true,
Port: "3476",
GRPCTargetHost: "127.0.0.1",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Keep server.host loopback-only by default.

Setting Host to "" makes the HTTP server bind :3476, i.e. all interfaces. That broadens network exposure on upgrade even though this change only needs to decouple the gateway dial target from the bind address. Please keep the bind default on loopback and use server.http.grpc_target_host only for the internal gRPC dial path.

Suggested fix
 		Server: Server{
 			NameOverride: "",
-			Host:         "",
+			Host:         "127.0.0.1",
 			HTTP: HTTP{
 				Enabled:        true,
 				Port:           "3476",
 				GRPCTargetHost: "127.0.0.1",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Host: "",
HTTP: HTTP{
Enabled: true,
Port: "3476",
Enabled: true,
Port: "3476",
GRPCTargetHost: "127.0.0.1",
Host: "127.0.0.1",
HTTP: HTTP{
Enabled: true,
Port: "3476",
GRPCTargetHost: "127.0.0.1",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/config/config.go` around lines 288 - 292, The server default
currently sets Host = "" which binds to all interfaces; change the default to
loopback-only by setting Host to "127.0.0.1" (or "::1" if IPv6 desired) while
leaving HTTP.GRPCTargetHost (server.http.grpc_target_host) unchanged for
internal gRPC dialing; update the default in the config struct where Host and
HTTP (Enabled, Port, GRPCTargetHost) are initialized so the HTTP server binds to
loopback by default but continues to use GRPCTargetHost for the internal dial
path.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.64%. Comparing base (3bc7f3b) to head (fcac8d1).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2824      +/-   ##
==========================================
+ Coverage   82.63%   82.64%   +0.02%     
==========================================
  Files          74       74              
  Lines        8126     8127       +1     
==========================================
+ Hits         6714     6716       +2     
+ Misses        893      892       -1     
  Partials      519      519              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@omer-topal omer-topal merged commit 79df6d7 into master Mar 10, 2026
15 checks passed
@omer-topal
Copy link
Copy Markdown
Contributor Author

solves #2800

@omer-topal omer-topal deleted the fix/separate-http-grpc-target-host branch March 10, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants